Skip to content
On this page

总结

  • wc
    • -l / --lines: 行数
    • -w / --words: 词数
    • -c / --bytes: 字节数
    • -m / --chars: 字符数
    • 字符集和字符编码
    • utf-8utf-16utf-32

提问

  • [x] 1. 如何显示某个文件的行数

    wc -l [ file ]

  • [x] 2. 某个文件字符数及字节数有何区别

    • 字节: 存储单位
    • 字符: 数字、字母、符号或中文。

    1 个英文字符为 1 字节,以 UTF-8 表示时,1 个汉字字符为 3 ~ 4 字节

1. 前提提要、场景

  • 文本内容正则匹配: grep
  • 文本内容排序: sort

如果想要统计文本内容行数、词数、字节数,可以使用 wc (word count) 的缩写

2. wc 统计文本内容行数、词数、字节数

sh
$ wc package.json
# 行 词数 字节数 文件名
153  458 7432 package.json

# -l:--lines 行数
$ wc -l package.json
153 package.json

# 如果仅仅想显示行数
$ cat package.json | wc -l
153

# -w:--words 词数
$ wc -w package.json
458 package.json

# -m:--chars 字符数
$ wc -m package.json
7432 package.json

# -c:--bytes 字节数
$ wc -c package.json
7432 package.json

3. 字节数和字符数

每个英文字符占 1 字节,以 utf-8 表示时,每个汉字字符占 3 ~ 4 字节。

sh
# 1 个 字符
# -n: 不输出尾部的换行符
$ echo -n  | wc -m
1 

# 3 个 字节
$ echo -n  | wc -c
3

4. 字符集和字符编码

4.1 字符集

字符集是很多个字符的集合

早期,制定了适用于英语字符的 ASCII 字符集。一共定义了 128 个字符。

随着发展,各个国家出现了更多字符集,大陆的 GB2312、港台的 BIG5

这便出现了个问题:一个网页文件有中英文,便至少要两套字符集去编码解析。如果再多些表情符号和数学公式...,需要加载太多套字符集了

为了在互联网有一套完整的字节集,定义世界各种语言的每个字符,便有了 Unicode 字符集。共定义了一百多万个字符。

字符集:

  • ASCII: 英语字符集(字母、数字、英语符号)。每个字符 1 个字节,共定义了 128 个字符(0x00 - 0x7F)。
  • GB2312: 大陆的简体字符集,2 字节
  • BIG5: 港台的繁体字符集,2 字节
  • GBK: 集合了简体字和繁体字的字符集,2 字节
  • Unicode: 国际标准字符集,为世界各种语言的每个字符定义一个唯一的编码。utf-8 编码中,每个字符 1 ~ 4 个字节,共定义了一百多万个字符(0x0000 - 0x10FFFF

ASCII 只用了 7128 个字符,是因为最高位用来做网络传输的奇偶校验了。
奇偶校验: 1 的个数为奇数,最高位为 1,偶数则为 0

4.2 字符编码

字符集是很多个字符的集合,而将字符集转换为字节或字节序列,以便在计算机中存储和通信网络中传输,这便需要字符编码。

  • ASCII、GB2312、GBK 等: 都是即表示了字符集,又表示了对应的字符编码,可以视为同义词
  • Unicode: 采用现代的模型,Unicode 字符集有多种字符编码。如 utf-8utf-16utf-32

也可以将字符集理解为规范,而字符编码是规范的实现。

4.3 utf-32

Unicode 字符集,每个字符最多占用 4 个字节。规范有了,但是要怎么去实现存储呢?
最简单的方式就是每个字符按最大占用算,直接每个字符都用 4 个字节存储。这是最简单的实现方式。

优点是编码速度很快,缺点是太占用空间了。

4.4 utf-8

为了避免浪费空间,便需要一种可变长度字符编码 utf-8

ASCII 的每个字符占用 1 个字节,是固定字节数。
utf-8 每个字符占用 1 ~ 4 字节,非固定字节数。非固定字节数就需要有标志,去作为字符与字符之间的区分。

utf-8 有个取巧的设计:

  • 如果该字节第一位为 0,这个字节单独为字符。
  • 如果该字节从第一位开始,连续有 n1,则字符占用 n 个字节。

可以在Unicode To UTF8 中查看他们的二进制编码

  • A: 01000001。1 字节
  • ĕ: 11000100|10010101。2 字节
  • : 11100101|10100101|10111101。3 字节
  • 🚀: 11110000|10011111|10011010|10000000。4 字节

Unicodeutf-8 占用字节:

  • 1 个字节:涵盖英语字符集。前 128 个字符,与 ASCII 编码相同,可以理解为 utf-8 兼容了 ASCII
  • 2 个字节:涵盖了几乎所有拉丁字母的其余部分,还包括希腊语等等。
  • 3 个字节:涵盖了中文、日文、韩文,包含了 GBK
  • 4 个字节:涵盖了表情符号、数学符号、扩展的非常用汉字等

可以看出来,在 GBK 中,中文只需要 2 字节。 urf-8 中由于需要字符数标志符,中文需要 3 字节。理论上如果内容只有中文,使用 GBK 更节省空间,但在实际网络中,中英文混用,甚至还有表情符号和数学公式,用 Unicodeutf-8 更省事。

utf-8 节省了空间,兼容了 ASCII ,但编码复杂了一些。

4.5 utf-16

utf-16 也是一种可变长编码,全都占用 2 字节,在纯英文上,存储能力比 utf-8 弱,但在中文或者更复杂的场景,存储能力比 utf-8 强。

优点:不需要字符标志,存储效率更高、执行索引操作时速度很快。

缺点:Unicode 5.0 已经收录快 10 万个字符了,而 utf-16 只有 6 万个字符,也需要扩展字节。容错性低。大小端字节序问题。

原理未梳理,有懂的大佬帮我捋一捋